package com.zcf.service;
import java.util.*;
import	java.util.stream.Collectors;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.zcf.common.json.Body;
import com.zcf.gameController.F_Websocket_s;
import com.zcf.gameController.WebSocketBull;
import com.zcf.gameController.gameUtils.gameLogic;
import com.zcf.pojo.HigherRoom;
import com.zcf.pojo.Pumping;
import com.zcf.pojo.RoomsParam;
import com.zcf.pojo.UserBean;
import com.zcf.vo.out.LayuiJson;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.websocket.Session;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author jj
 * @date 2019/11/9 18:41
 */
@Service
public class GameRoomServiceImpl {
    private Gson gson = new GsonBuilder() .setExclusionStrategies(new ExclusionStrategy() {
        @Override
        public boolean shouldSkipField(FieldAttributes f) {
            return false;
        }
        @Override
        public boolean shouldSkipClass(Class<?> incomingClass) {
            return incomingClass == Session.class;
        }
    }) .create();
    /**
    * @description :创建房间
    * @param room 
    * @date : 2019/11/9 18:53
    * @author : jj
    */
    @Transactional(rollbackFor = Exception.class)
    public Body addRoom(HigherRoom room){
        if (room==null){
            return Body.BODY_470;
        }
        room.setRoomNum((int)((Math.random()*4+1)*100000)+"");
        room.setCreateTime(new Date());
        room.setState(0);
        if (room.getGameType()==0){
            room.setPostions(5);
        }else {
            room.setPostions(8);
        }
        boolean b = room.insert();
        return b?Body.newInstance():Body.BODY_470;
    }
    /**
     * @description :更新房间
     * @param room
     * @date : 2019/11/9 18:53
     * @author : jj
     */
    @Transactional(rollbackFor = Exception.class)
    public Body updateRoom(HigherRoom room){
        if (room==null){
            return Body.BODY_470;
        }
        boolean b = room.updateById();
        return b?Body.newInstance():Body.BODY_470;
    }
    /**
    * @description :查询所有房间
    * @date : 2019/11/9 19:10
    * @author : jj
    */
    public LayuiJson listRooms(int pagenum,int pagesize){
        HigherRoom higherRoom = new HigherRoom();
        LayuiJson lj = new LayuiJson();
        Page<HigherRoom> higherRoomPage = higherRoom.selectPage(new Page<>(pagenum, pagesize), new EntityWrapper<>(null));
        if (higherRoomPage.getRecords() == null || higherRoomPage.getRecords().size()==0) {
            lj.setCode(1);
            lj.setMsg("无数据");
            lj.setCount(0);
            lj.setData(null);
            return lj;
        }
        int num = higherRoom.selectCount(new EntityWrapper<>(null));
        lj.setCode(0);
        lj.setMsg("yes");
        lj.setCount(num);
        lj.setData(higherRoomPage.getRecords());
        return lj;
    }

    /**
     * 查找房间
     * @param roomNum
     * @return
     */
    public  Body bitRoom(String roomNum){
        RoomsParam roomsParam=null;
        roomsParam = F_Websocket_s.rooms.get(roomNum);
        if (roomsParam!=null){
            return Body.newInstance(roomsParam.getGametype());
        }
        roomsParam = WebSocketBull.rooms.get(roomNum);
        if (roomsParam != null){
            return Body.newInstance(roomsParam.getGametype());
        }
        return  Body.newInstance(470,"房间不存在");
    }

      /**
      * @description :查询分类房间
      * @param gameType
      * @param roomGrade
      * @date : 2019/11/9 19:10
      * @author : jj
      */
    public Body listClassifyRooms(Integer gameType,Integer roomGrade){
        List<RoomsParam> roomsParams=null;
        if (gameType==null||roomGrade==null){
            return Body.newInstance(460,"参数错误");
        }
        if (gameType==0){
           roomsParams  = WebSocketBull.rooms.values().stream().filter(roomsParam->roomsParam.getRoomGrade().equals(roomGrade)).collect(Collectors.toList());
        }else {
           roomsParams  = F_Websocket_s.rooms.values().stream().filter(roomsParam->roomsParam.getRoomGrade().equals(roomGrade)).collect(Collectors.toList());
        }
        if (roomsParams==null||roomsParams.size()==0){
            return Body.newInstance(460,"没有房间");
        }

        return Body.newInstance(gson.toJson(roomsParams));
    }
    /**
     * 开启房间
     */
    @Transactional(rollbackFor = Exception.class)
    public Body openRoom( Long id, Integer state){
        HigherRoom higherRoom=new HigherRoom();
        HigherRoom room = higherRoom.selectById(id);
        room.setState(state);
        boolean b = room.updateById();
        if (b){
            try {
                Body puming = puming(room);
                if (puming!=null){
                    return puming;
                }
                addGameList(room);
                return Body.newInstance();
            }catch (Exception e){
                System.out.println("开启出现问题");
                return Body.BODY_470;
            }
        }
        return Body.BODY_470;
    }


    /**
     * 关闭房间
     */
    @Transactional(rollbackFor = Exception.class)
    public Body closeRoom( Long id, Integer state){
        HigherRoom higherRoom=new HigherRoom();
        HigherRoom room = higherRoom.selectById(id);
        room.setState(state);
        boolean b = room.updateById();
        if (b){
            try {
                clsoeGameList(room);
            }catch (Exception e){
                System.out.println("关闭出现问题");
                return Body.BODY_470;
            }
            return Body.newInstance();
        }
        return Body.BODY_470;
    }

    /**
     * 加入房间集合
     * @param room
     */
    private void addGameList(HigherRoom room){
        Integer type = room.getGameType();
        RoomsParam roomsParam=new RoomsParam();
        roomsParam.setRoomName(room.getRoomNum());
        roomsParam.setGametype(room.getGameType());
        roomsParam.setPumping(room.getPumping());
        roomsParam.setRoomPoints(room.getRoomPoints());
        roomsParam.setBankerMoney(room.getBankerMoney());
        roomsParam.setRoomGrade(room.getRoomGrade());
        Map<String, Integer> map = new HashMap();
        map.put("setupTime",10);
        map.put("robsTime",30);
        map.put("bettonTime",120);
        map.put("brightBrandTime",10);
        roomsParam.setRoomType(map);
        roomsParam.setTimer(map.get("setupTime"));
        map.put("postionNum",room.getPostions());
        List<Integer> postions = new ArrayList<>();
        for(int i = 0;i<room.getPostions();i++){
            postions.add(0);
        }
        roomsParam.setRoomCards(gameLogic.getCards(roomsParam.getGametype()));
        roomsParam.setPostions(postions);
        roomsParam.setUsers(new HashMap<String, UserBean>());
        roomsParam.setLock(new ReentrantLock());
        roomsParam.setCards(new HashMap<>());
        roomsParam.setIsUp(0L);
        roomsParam.setIsStart(0);
        roomsParam.setBetMap(new HashMap<>());
        roomsParam.setBetMoeny(new HashMap<>());
        if (roomsParam.getGametype()>0){
            for (int i=0;i<roomsParam.getPostions().size();i++){
                roomsParam.getBetMoeny().put(i,0);
            }
        }else {
            for (int i=0;i<roomsParam.getPostions().size()-1;i++){
                roomsParam.getBetMoeny().put(i,0);
            }
        }
        roomsParam.setBunko(new HashMap<>());
        roomsParam.setCards(new HashMap<>());
        roomsParam.setNumber_rounds(0);
        if (type>0){
            F_Websocket_s.rooms.put(room.getRoomNum()+"",roomsParam);
        }else {
            WebSocketBull.rooms.put(room.getRoomNum()+"",roomsParam);
        }
    }

    /**
    * @description :关闭房间
    * @param room
    * @date : 2019/11/27 17:48
    * @author : jj
    */
    private void clsoeGameList(HigherRoom room){
        RoomsParam roomsParam=null;
        Integer type = room.getGameType();
        if (type>0){
            roomsParam = F_Websocket_s.rooms.get(room.getRoomNum() + "");
            if (roomsParam!=null){
                if (roomsParam.getUsers().size()>0){
                    roomsParam.setIsStart(0);
                    for (UserBean userBean : roomsParam.getUsers().values()) {
                        F_Websocket_s f_websocket_s = F_Websocket_s.clients.get(userBean + "");
                        try {
                            f_websocket_s.disConnect(userBean.getId(),userBean.getSession());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        F_Websocket_s.clients.remove(userBean + "");
                    }
                }
                F_Websocket_s.rooms.remove(room.getRoomNum() + "");
            }
        }else {
            roomsParam= WebSocketBull.rooms.get(room.getRoomNum()+"");
            if (roomsParam!=null){
                if (roomsParam.getUsers().size()>0){
                    roomsParam.setIsStart(0);
                    for (UserBean userBean : roomsParam.getUsers().values()) {
                        WebSocketBull webSocketBull = WebSocketBull.clients.get(userBean + "");
                        try {
                            webSocketBull.disConnect(userBean.getId(),userBean.getSession());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        WebSocketBull.clients.remove(userBean + "");
                    }
                }
                WebSocketBull.rooms.remove(room.getRoomNum() + "");
            }
        }
        System.gc();
    }

    /**
    * @description :加入房间设置
    * @param room 
    * @date : 2019/11/27 17:48
    * @author : jj
    */
    private  Body puming(HigherRoom room){
        Pumping pumping=new Pumping();
        Pumping pump = pumping.selectOne(new EntityWrapper()
                .eq("game_type", room.getGameType())
                .eq("room_grade",room.getRoomGrade()));
        if (pump==null){
            return Body.BODY_470;
        }
        room.setPumping(pump.getPumping()/100);
        room.setBankerMoney(pump.getBankerMoney());
        if (room.getRoomPoints()==null){
            room.setRoomPoints(pump.getRoomPoints());
        }
        return null;
    }

}
